/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ticketmaster.businesslogic;

import java.util.Collection;
import ticketmaster.businessobject.PurchaseType;
import ticketmaster.businessobject.ShoppingCart;
import ticketmaster.businessobject.Ticket;
import ticketmaster.common.PaymentStatus;
import ticketmaster.common.PurchaseTypes;
import ticketmaster.dao.BankcardDAO;
import ticketmaster.dao.BookedTicketDAO;
import ticketmaster.dao.DAOFactory;
import ticketmaster.dataobject.Bankcard;
import ticketmaster.dataobject.BookedTicket;
import ticketmaster.dataobject.Order;
import ticketmaster.dataobject.Transaction;
import ticketmaster.util.DateTimeHelper;

/**
 *
 * @author Wei Liu
 */
public class PaymentController
{

    public boolean isCreditCardValid(Bankcard creditCard)
    {
        BankcardDAO bankcardDAO = DAOFactory.getInstance().getBankcardDAO();
        if (bankcardDAO.getBankcardsDO(creditCard).isEmpty())
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    private void processCreditCard(Order order, Bankcard creditCard, Transaction transaction) throws Exception
    {
        TransactionController transactionController = new TransactionController();
        BankcardController bankcardController = new BankcardController();

        if ((creditCard.getBalance() - order.getCost()) < 0)
        {
            transaction.setPaymentStatusID(PaymentStatus.Failed.ordinal());
            transactionController.updateTransaction(transaction);
            throw new Exception("Not enough balance. Purchase Failed.");
        }
        else
        {
            creditCard.setBalance(creditCard.getBalance() - order.getCost());
            bankcardController.UpdateBankcard(creditCard);

            transaction.setPaymentStatusID(PaymentStatus.Completed.ordinal());
            transactionController.updateTransaction(transaction);

            OrderController orderController = new OrderController();
            order.setPaymentDate(DateTimeHelper.getCurrentDateTime());
            orderController.updateOrder(order);
        }
    }

    private void updateBookedTickets(int transactionID, Collection<BookedTicket> tickets)
    {
        BookedTicketDAO bookedTicketDAO = DAOFactory.getInstance().getBookedTicketDAO();
        for(BookedTicket ticket : tickets)
        {
            ticket.setIsPaid(true);
            ticket.setTransactionID(transactionID);
            bookedTicketDAO.updateBookedTicket(ticket);
        }
    }

    public void payFee(Order order, Bankcard creditCard, Collection<BookedTicket> tickets) throws Exception
    {
        if (!isCreditCardValid(creditCard))
        {
            throw new Exception("Credit card information is not valid");
        }
        else
        {
            BankcardController bankcardController = new BankcardController();

            creditCard = bankcardController.getCreditCard(creditCard);
            creditCard.setCustomerID(order.getCustomerID());
            bankcardController.UpdateBankcard(creditCard);

            Transaction transaction = new Transaction();
            transaction.setBankCardID(creditCard.getBankCardID());
            transaction.setOrderID(order.getOrderID());
            transaction.setPaymentStatusID(PaymentStatus.New.ordinal());

            TransactionController transactionController = new TransactionController();
            transaction.setTransactionID(transactionController.createTransaction(transaction));

            this.processCreditCard(order, creditCard, transaction);
            
            if(tickets != null)
            {
                this.updateBookedTickets(transaction.getTransactionID(), tickets);
            }

            if(PurchaseType.getPurchaseType() != PurchaseTypes.Normal)
            {
                updatePremiumMembership();
            }
        }

    }

    private void updatePremiumMembership()
    {
        PremiumCustomerController controller = new PremiumCustomerController();

        if(PurchaseType.getPurchaseType() == PurchaseTypes.Upgrade || PurchaseType.getPurchaseType() == PurchaseTypes.New)
        {
            controller.createNewPremium();
        }
        else if(PurchaseType.getPurchaseType() == PurchaseTypes.Continue)
        {
            controller.postponePremiumExpireDate();
        }
    }
}
